<?php
class wapi_apps extends wapi_mod_base {
	private $com_prefix = 'com_';
	public $apps = array();
	private $session_vars = array();

	function _construct(){
		global $wapi;
		if ($this->firstrun){
			$this->db_create();
		}
		if (isset($_SESSION['WAPI_APPS_RUNNING']) && is_array($_SESSION['WAPI_APPS_RUNNING'])){
			$wapi->user->running = $_SESSION['WAPI_APPS_RUNNING'];
		}
	}
	private function db_create(){
		global $wapi;
		// Called on wapi user first run
		$sql = "CREATE TABLE apps (
		app_class TEXT UNIQUE NOT NULL,
		title TEXT NOT NULL,
		version TEXT NOT NULL,
		time_installed TEXT NOT NULL
		)";
		$wapi->db->exec($sql);
		$this->register('menu','App Menu','0.1');
		$this->register('admin','Admin','0.1');
		$this->register('installer','Installer','0.1');
		$this->register('debug','Debugger','0.1');
		$this->register('pcapa','PCAPA','0.01');
	}
	private function db_user_create(){
		global $wapi;
		if ($wapi->db_user->table_exists('apps')){
			return false;
		}
		// Called on user first run
		$sql = "CREATE TABLE apps (
		app_class TEXT UNIQUE NOT NULL,
		show INTEGER NOT NULL,
		time_enabled TEXT NOT NULL,
		last_boot TEXT,
		last_com TEXT,
		last_poll TEXT
		)";
		$wapi->db_user->exec($sql);
		$this->enable('menu');
		$this->enable('admin');
		$this->enable('installer');
		$this->enable('debug');
		$this->enable('pcapa');
	}
	function poll(){
		global $wapi;
		if ($this->polled) return false;
		$this->polled = true;
		$wapi->job->type = 'poll';
		foreach ($this->apps as $k => $app){
			if (isset($wapi->user->running[$k])){
				// Running poll NOW
				$wapi->job->app = $k;
				$wapi->poll_resp_exists($k,true);
				ob_start();
				$wapi->resp->poll_resp[$k]->data = $app->poll();
				$wapi->resp->poll_resp[$k]->text = ob_get_clean();
				$wapi->job->app = '';
			}
		}
		$wapi->job->type = '';
	}
	function unload($app_class){
		if (isset($this->apps[$app_class])){
			unset($this->apps[$app_class]);
		}
		return true;
	}
	function resources($app_class){
		if ($this->load($app_class)){
			return $this->apps[$app_class]->resources;
		} else {
			$ret = array();
			return array();
		}
	}
	function load($app_class){
		global $wapi;
		if (isset($this->apps[$app_class])){
			// already loaded
			return true;
		}
    	if ($this->is_enabled($app_class)) {
    		// load it
			$this->apps[$app_class] = new $app_class();
			return true;
		}
		return false;
	}
	function load_all(){
		global $wapi;
		foreach ($wapi->user->running as $k => $v) {
			$this->load($k);
		}
	}
	function unload_all(){
		global $wapi;

	}
	function is_enabled($app_class){
		global $wapi;
		$sql = "SELECT app_class FROM apps WHERE app_class = '$app_class'";
		if ($wapi->db_user->query($sql)){
			return true;
		}
		return false;
	}
	function is_installed($app_class){
		global $wapi;
		$sql = "SELECT app_class FROM apps WHERE app_class = '$app_class'";
		if ($wapi->db->query($sql)){
			return true;
		}
		return false;
	}
	function is_loaded($app_class){
		return isset($this->apps[$app_class]);
	}
	function event_poll(){
		$stopit = '';
	}
	function com($app_class,$func,$data){
		global $wapi;
		$args = array();
		$args[] = $data;
		$func = $this->com_prefix . $func;
		if ($app_class == 'wapi'){
			// TODO check permissions to run this wapi method
			if (method_exists($wapi, $func)){
				return call_user_func_array(array($wapi,$func), $args);
			}
		} elseif ($this->load($app_class)){
			if (method_exists($this->apps[$app_class], $func)){
				return call_user_func_array(array($this->apps[$app_class], $func), $args);
			}
		}
		return null;
	}
	function install($app_class){
		global $wapi;
		$app_info = $wapi->apps_path . '/' . $wapi->apps_path  . '/' . $app_class . '/info.html';
		if (file_exists($app_info)){
			$info_str = file_get_cotnents($app_info);

		}
	}
	function uninstall($app_class){
		if ($this->is_installed($app_class)){
			$sql = "DELETE FROM apps WHERE app_class = '$app_class'";
			if ($wapi->db->exec($sql) == 1) {
				return true;
			}
			return false;
		}
	}
	function enable($app_class,$enable=true){
		global $wapi;
		if ($enable) {
			if ($this->is_installed($app_class)){
				$now = date("Y-m-d H:i:s",time());
				$vals = "'$app_class',1,'$now'";
				$sql = 'INSERT INTO apps (app_class,show,time_enabled) VALUES ('.$vals.')';
				if ($wapi->db_user->exec($sql) == 1) {
					return true;
				}
				return false;
			}
		} else {
			if ($this->is_enabled($app_class)){
				$sql = "DELETE FROM apps WHERE app_class = '$app_class'";
				if ($wapi->db_user->exec($sql) == 1) {
					return true;
				}
				return false;
			}
		}
	}
    public function __get($name){
        $fn_name = 'get_' . $name;
        if (method_exists($this, $fn_name)){
            return $this->$fn_name();
        } else {
			if (in_array($name,$this->session_vars)){
	        	$backtrace = debug_backtrace();
				$svar = $backtrace[0]['class'] . '_' . $name;
				if (isset($_SESSION[$svar])){
					return $_SESSION[$svar];
				}
			}
        }
        if (array_key_exists($name,$this->apps)){
        	return $this->apps[$name];
        }
        return null;
    }
    public function __set($name, $value){
        $fn_name = 'set_' . $name;
        if (method_exists($this, $fn_name)){
            $this->$fn_name($value);
            return true;
        } else {
			if (in_array($name,$this->session_vars)){
				$backtrace = debug_backtrace();
				$svar = $backtrace[0]['class'] . '_' . $name;
				$_SESSION[$svar] = $value;
				return true;
			}
        }
        return false;
    }
//    private function app_save_to_db_user($app_class){
//    	if (isset($this->apps[$app_class])) {
//	    	$sql = "CREATE TABLE app_instances (app_class TEXT UNIQUE NOT NULL,instance_data TEXT NOT NULL)";
//			if ($this->db_user->table_exists('app_instances',$sql)){
//				$this->apps[$app_class]->_sleep();
//				$instance_data = base64_encode(serialize($this->apps[$app_class]));
//	    		$sql = "INSERT OR REPLACE INTO app_instances (app_class,instance_data) values ('$app_class','$instance_data')";
//				return $this->db_user->exec($sql);
//			}
//    	}
//    	return false;
//    }
//    private function app_load_from_db_user($app_class){
//    	if (!isset($this->apps[$app_class])){
//	    	$sql = "SELECT instance_data FROM app_instances WHERE app_class='$app_class'";
//			if ($this->db_user->query($sql)){
//				$res = $this->db_user->results;
//	    		foreach ($res as $row){
//		        	$this->apps[$app_class] = unserialize(base64_decode($row['instance_data']));
//		        	$this->apps[$app_class]->size = strlen($row['instance_data']);
//		        	return true;
//		        }
//	    	}
//    	}
//		return false;
//    }
//    function app_load($app_class,$allow_new_instance=true,$force_refresh=false){
//    	if (!isset($this->apps[$app_class]) || $force_refresh) {
//    		$app_file = $this->base_path . $this->apps_path . '/' . $app_class . '/app.php';
//			if (file_exists($app_file)) {
//				// This is the only place we create/load app instances
//				// TODO do permissions check here
//				if (!$this->app_load_from_db_user($app_class) && $allow_new_instance){
//					$this->apps[$app_class] = new $app_class();
//				}
//				return true;
//			}
//    	} else {
//    		return true;
//    	}
//    }
//	private function apps_load($force_refresh=false){
//    	$sql = "SELECT app_class FROM app_instances";
//		if ($this->db_user->query($sql)){
//			$res = $this->db_user->results;
//    		foreach ($res as $row){
//		        $this->app_load($row['app_class'],false);
//	        }
//    	}
//    	$res = null;
//	}
//    function is_loaded($app_class){
//    	if ($app_class == '' || $app_class == null)
//    		return false;
//    	return isset($this->apps[$app_class]);
//    }
//    function is_sleeping($app_class){
//    	if ($app_class == '' || $app_class == null)
//    		return false;
//    	$sql = "SELECT app_class FROM app_instances WHERE app_class='$app_class'";
//		if ($this->db_user->query($sql)){
//			return true;
//    	} else {
//    		return false;
//    	}
//    }

//	function app_unload($app_class){
//		if (isset($this->apps[$app_class])) {
//			if (method_exists($this->apps[$app_class],'app_unload'))
//				$this->apps[$app_class]->app_unload();
//			//if ($this->db_user->table_exists('app_instances')){
//    		$sql = "DELETE FROM app_instances WHERE app_class = '$app_class'";
////    		$this->db_user = null;
////    		$this->db_user = $this->get_app_db($this->class,true);
//			if ($this->db_user->exec($sql) == -1){
//				$tmp = $this->db_user->error;
//				$stop = '';
//			}
//			//}
//			unset($this->apps[$app_class]);
//			if ($app_class == $this->app_has_focus) {
//				$this->app_has_focus = '';
//			}
//    	}
//	}
	public function install_from_path($path){
		// TODO Below code is totally broken.
		// If the $path isn't in the default apps path
		// read the xml file. validate it and create a new app folder in the
		// default apps path with the name of the class
		if (file_exists($fullpath . '/app.xml')){
			$xmlstr = file_get_contents($fullpath . '/app.xml');
			$xml = new SimpleXMLElement($xmlstr);
			$app_name = (string) $xml->name;
			$app_class = (string) $xml->class_name;
			$xml = null;
                $sajaFunc = $fullpath . '/app.php';
                $appfile = $fullpath . '/index.php';
                // TODO validate classname and appname
                if ($app_name != '') {
                if (file_exists($sajaFunc) && $app_class != '') {
                	$this->app_add($app_name, $app_class, 'app', true, $force_update);
                } elseif (file_exists($appfile)) {
					$this->app_add($app_name, $app_class, 'index', true, $force_update);
                    }
                }
		}
	}
	public function user_app_list(){
		global $wapi;
		$apps = array();
		$sql = "SELECT app_class FROM apps";
		if ($wapi->db_user->query($sql)) {
			$res = $wapi->db_user->results;
			foreach ($res as $r){
				$app_class = $r['app_class'];
				// load app info
				$sql = "SELECT * FROM apps WHERE app_class = '$app_class'";
				if ($wapi->db->query($sql)){
					$wres = $wapi->db->results;
					$apps[] = $wres[0];
				}
			}
		}
		return $apps;
	}
	public function event_user_loaded(){
		$this->db_user_create();
		global $wapi;
		$wapi->user->app_list = $this->user_app_list();
	}
	public function register($app_class,$title,$version,$force_update=false) {
		global $wapi;
		if ($force_update) {
			$sql = "INSERT OR REPLACE";
		} else {
			$sql = "INSERT";
		}
		$now = date("Y-m-d H:i:s",time());
		$vals = "'$app_class','$title','$version','$now'";
		$sql = 'INSERT INTO apps (app_class,title,version,time_installed) VALUES ('.$vals.')';
		if ($wapi->db->exec($sql) == 1) {
			return true;
		}
		return false;
	}
}
?>